package com.dhcc.core.modules.system.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.dhcc.core.framework.base.service.impl.BaseServiceImpl;
import com.dhcc.core.framework.constant.Const;
import com.dhcc.core.framework.constant.state.ManagerStatus;
import com.dhcc.core.framework.constant.state.PositionType;
import com.dhcc.core.framework.datascope.DataScope;
import com.dhcc.core.framework.exception.BizException;
import com.dhcc.core.framework.exception.BizExceptionEnum;
import com.dhcc.core.framework.result.node.ZTreeNode;
import com.dhcc.core.framework.security.ShiroKit;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.DateUtil;
import com.dhcc.core.framework.util.JsonUtil;
import com.dhcc.core.framework.util.PinyinUtil;
import com.dhcc.core.modules.system.cache.dept.DeptCache;
import com.dhcc.core.modules.system.cache.role.RoleCache;
import com.dhcc.core.modules.system.dao.DeptMapper;
import com.dhcc.core.modules.system.dao.DeptUserMapper;
import com.dhcc.core.modules.system.dao.RoleMapper;
import com.dhcc.core.modules.system.dao.UserMapper;
import com.dhcc.core.modules.system.entity.Dept;
import com.dhcc.core.modules.system.entity.DeptUser;
import com.dhcc.core.modules.system.entity.Position;
import com.dhcc.core.modules.system.entity.Role;
import com.dhcc.core.modules.system.entity.User;
import com.dhcc.core.modules.system.factory.UserFactory;
import com.dhcc.core.modules.system.service.IDeptService;
import com.dhcc.core.modules.system.service.IPositionService;
import com.dhcc.core.modules.system.service.IUserService;
import com.dhcc.core.modules.system.transfer.DeptRoleDto;
import com.dhcc.core.modules.system.transfer.UserDto;
import com.dhcc.core.modules.system.vo.ExportUserVo;

/**
 * 用户表数据服务层接口
 * 
 * @ClassName: UserServiceImpl
 * @Description: TODO
 * @author: cyf
 * @date: 2018年1月2日 上午10:41:41
 */
@Service("userService")
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    DeptUserMapper deptUserMapper;
    
    @Autowired
    IDeptService deptService;
    
    @Autowired
    IPositionService positionService;
    
    @Autowired
    DeptMapper deptMapper;
    @Autowired
    RoleMapper roleMapper;

    @Override
    @Transactional
    public User addUser(UserDto user, String deptRole) {
        // 判断账号是否重复
        User theUser = this.baseMapper.getByLoginName(user.getLoginName());
        if (theUser != null) {
            throw new BizException(BizExceptionEnum.USER_ALREADY_REG);
        }

        // 判断账号是否重复
        Wrapper<User> wrapper = new EntityWrapper<User>();
        wrapper.eq("user_code", user.getUserCode());
        int count = this.baseMapper.selectCount(wrapper);
        if (count > 0) {
            throw new BizException(BizExceptionEnum.USER_ALREADY_REG);
        }
        // 完善账号信息
        user.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(user.getPassword(), user.getSalt()));
        user.setStatus(ManagerStatus.OK.getCode());
        
        //添加首字母与全拼信息
        user.setInitials(PinyinUtil.converterToFirstSpell(user.getName()));
        user.setPinyin(PinyinUtil.converterToSpell(user.getName()));
        
        User newUser = UserFactory.createUser(user);
        this.baseMapper.insert(newUser);
        // 保存部门用户关系 表
        if(CommonUtil.isNotEmpty(deptRole)){
            List<DeptUser> ls = JsonUtil.toList(deptRole, DeptUser.class);
            for (DeptUser deptUser : ls) {
                if(deptUser.getIsPartTime()==0){
                    newUser.setDeptId(deptUser.getDeptId());
                    newUser.updateById();
                }
                deptUser.setRoleIds(CommonUtil.idsStrFormat(deptUser.getRoleIds(), true));
                deptUser.setUserId(newUser.getId());
                deptUser.setDeptId(deptUser.getDeptId()==0?null:deptUser.getDeptId());
                deptUser.insert();
            }
        }
        return newUser;
    }

    @Override
    @Transactional
    public User updateUser(UserDto user, String deptRole) {
        User oldUser = this.baseMapper.selectById(user.getId());
        // 判断账号是否重复
        if (!CommonUtil.equals(user.getLoginName(), oldUser.getLoginName())) {
            User theUser = baseMapper.getByLoginName(user.getLoginName());
            if (theUser != null) {
                throw new BizException(BizExceptionEnum.USER_ALREADY_REG);
            }
        }

        // 判断账号是否重复
        if (!CommonUtil.equals(user.getUserCode(), oldUser.getUserCode())) {
            Wrapper<User> wrapper = new EntityWrapper<User>();
            wrapper.eq("user_code", user.getUserCode());
            int count = this.baseMapper.selectCount(wrapper);
            if (count > 0) {
                throw new BizException(BizExceptionEnum.USER_ALREADY_REG);
            }
        }
        
        //添加首字母与全拼信息
        user.setInitials(PinyinUtil.converterToFirstSpell(user.getName()));
        user.setPinyin(PinyinUtil.converterToSpell(user.getName()));

        User newUser = UserFactory.createUser(user);
        if (ShiroKit.hasRole(Const.ADMIN_NAME)) {
            this.baseMapper.updateById(newUser);
            // 删除部门用户关系 表
            Wrapper<DeptUser> wrapper1 = new EntityWrapper<DeptUser>();
            wrapper1.eq("user_id", oldUser.getId());
            deptUserMapper.delete(wrapper1);
            // 保存部门用户关系 表
            if(CommonUtil.isNotEmpty(deptRole)){
                List<DeptUser> ls = JsonUtil.toList(deptRole, DeptUser.class);
                for (DeptUser deptUser : ls) {
                    if(deptUser.getIsPartTime()==0){
                        newUser.setDeptId(deptUser.getDeptId());
                        newUser.updateById();
                    }
                    deptUser.setRoleIds(CommonUtil.idsStrFormat(deptUser.getRoleIds(), true));
                    deptUser.setUserId(newUser.getId());
                    deptUser.setDeptId(deptUser.getDeptId()==0?null:deptUser.getDeptId());
                    deptUser.insert();
                }
            }
        } else {
            User currUser = ShiroKit.getUser();
            if (currUser.getId().equals(user.getId())) {
                this.baseMapper.updateById(newUser);
                // 删除部门用户关系 表
                Wrapper<DeptUser> wrapper1 = new EntityWrapper<DeptUser>();
                wrapper1.eq("user_id", oldUser.getId());
                deptUserMapper.delete(wrapper1);
                // 保存部门用户关系 表
                if(CommonUtil.isNotEmpty(deptRole)){
                    List<DeptUser> ls = JsonUtil.toList(deptRole, DeptUser.class);
                    for (DeptUser deptUser : ls) {
                        if(deptUser.getIsPartTime()==0){
                            newUser.setDeptId(deptUser.getDeptId());
                            newUser.updateById();
                        }
                        deptUser.setRoleIds(CommonUtil.idsStrFormat(deptUser.getRoleIds(), true));
                        deptUser.setUserId(newUser.getId());
                        deptUser.setDeptId(deptUser.getDeptId()==0?null:deptUser.getDeptId());
                        deptUser.insert();
                    }
                }
            } else {
                throw new BizException(BizExceptionEnum.NO_PERMITION);
            }
        }
        return newUser;
    }

    @Override
    public int setStatus(Long userId, int status) {
        return this.baseMapper.setStatus(userId, status);
    }

    @Override
    public int changePwd(Long userId, String pwd) {
        User user = this.baseMapper.selectById(userId);
        return this.baseMapper.changePwd(userId, ShiroKit.md5(pwd, user.getSalt()));
    }

    @Override
    public List<Map<String, Object>> selectUsers(DataScope dataScope,Page<User> page, String name, String beginTime, String endTime,
            Long deptId) {
        return this.baseMapper.selectUsers(dataScope,page, name, beginTime, endTime, deptId);
    }


    @Override
    public User getByLoginName(String loginName) {
        return this.baseMapper.getByLoginName(loginName);
    }


    @Override
    public User selectUserByCode(String code) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("user_code", code);
        return this.selectOne(wrapper);
    }

    @Override
    public List<User> selectUsersByDeptId(Long deptId) {
        return this.baseMapper.selectUsersByDeptId(deptId);
    }

    @Override
    public String selectRoleIdsByUserId(Long userId) {
        Wrapper<DeptUser> wrapper = new EntityWrapper<>();
        wrapper.eq("user_id", userId);
        List<DeptUser> ls = this.deptUserMapper.selectList(wrapper);
        if(ls!=null&&ls.size()>0){
            String ids = "";
            for (DeptUser du : ls) {
                if(CommonUtil.isNotEmpty(ids)){
                    ids += ","+du.getRoleIds();
                }else{
                    ids = du.getRoleIds();
                }
            }
            return ids;
        }
        return null;
    }

    @Override
    public String selectRoleIdsByUser(Long userId,Long deptId) {
        DeptUser wrapper = new DeptUser();
        wrapper.setUserId(userId);
        wrapper.setDeptId(deptId);
        DeptUser du = this.deptUserMapper.selectOne(wrapper);
        if(du!=null){
            return du.getRoleIds();
        }
        return null;
    }

    @Override
    public boolean setRoles(Long userId, Long deptId, String roleIds) {
        DeptUser we = new DeptUser();
        we.setUserId(userId);
        we.setDeptId(deptId);
        DeptUser du = this.deptUserMapper.selectOne(we);
        du.setRoleIds(roleIds);
        
        return du.updateById();
    }

    @Override
    public List<DeptRoleDto> getDeptRoles(Long userId) {
        Wrapper<DeptUser> wrapper = new EntityWrapper<>();
        wrapper.eq("user_id", userId);
        List<DeptUser> ls = this.deptUserMapper.selectList(wrapper);
        if(CommonUtil.isNotEmpty(ls)){
            List<DeptRoleDto> res = new ArrayList<>();
            for (DeptUser du : ls) {
                DeptRoleDto drd = new DeptRoleDto();
                drd.setId(du.getId());
                drd.setDeptId(du.getDeptId());
                drd.setUserId(du.getUserId());
                drd.setRoleIds(CommonUtil.idsStrFormat(du.getRoleIds(), false));
                drd.setIsPartTime(du.getIsPartTime());
                drd.setDeptName(DeptCache.me().getDeptNameById(du.getDeptId()));
                drd.setRoleNames(RoleCache.me().getRoleNamesByIds(du.getRoleIds()));
                drd.setDeptCode(DeptCache.me().getDeptCodeById(du.getDeptId()));
                drd.setRoleCodes(RoleCache.me().getRoleCodesByIds(du.getRoleIds()));
                res.add(drd);
            }
            return res;
        }
        return null;
    }

    @Override
    public List<ExportUserVo> exportUsers(String name, String beginTime, String endTime, Long deptid) {
        return this.baseMapper.exportUsers(name, beginTime, endTime, deptid);
    }

    @Override
    @Transactional
    public void importUsers(List<List<Object>> all) {
        for (int i = 1; i < all.size(); i++) {
            List<Object> ls = all.get(i);
            String deptCode = ls.get(0).toString();
            String deptName = ls.get(1).toString();
            String deptFullname = ls.get(2).toString();
            String loginName = ls.get(3).toString();
            String userCode = ls.get(4).toString();
            String name = ls.get(5).toString();
            Date birthday = DateUtil.parseDate(ls.get(6).toString());
            Integer sex = CommonUtil.equals(ls.get(7),"男")?1:2;
            String email = ls.get(8).toString();
            String phone = ls.get(9).toString();
            String positionCode = ls.get(10).toString();
            String positionName = ls.get(11).toString();
            String roleCode = ls.get(12).toString();
            String roleName = ls.get(13).toString();

            // 看看有没有部门，没有就建一个吧
            Dept dept = this.deptService.selectByCode(deptCode);
            if (dept == null&&CommonUtil.isNotEmpty(deptCode)) {
                dept = new Dept();
                dept.setCode(deptCode);
                dept.setName(deptName);
                dept.setFullname(deptFullname);
                dept.setWeight(1);
                dept.init();
                dept.insert();
            }
            Long deptId = dept!=null?dept.getId():null;

            // 看看有没有职务，没有就建一个吧
            Position position = this.positionService.selectByCode(positionCode);
            if (position == null&&CommonUtil.isNotEmpty(positionCode)) {
                position = new Position();
                position.setCode(positionCode);
                position.setName(positionName);
                position.setLevels(PositionType.OTHER.getCode());
                position.setWeight(1);
                position.insert();
            }
            Long positionId = position!=null?position.getId():null;
            
            //看看有没有角色 没有就新建一个吧
            Role role = new Role();
            role.setCode(roleCode);;
            role = this.roleMapper.selectOne(role);
            if(role==null&&CommonUtil.isNotEmpty(roleCode)) {
            	role = new Role();
            	role.setCode(roleCode);
            	role.setName(roleName);
            	role.setWeight(1);
            	role.setParentId(0L);
            	role.insert();
            }
            Long roleId = role!=null?role.getId():null;
            // 判断账号是否重复
            User user = this.baseMapper.getByLoginName(loginName);
            if (user == null) {
                user = this.selectUserByCode(userCode);
            }
            
            if(user==null){
                user = new User();
                user.setLoginName(loginName);
                user.setUserCode(userCode);
                user.setName(name);
                user.setBirthday(birthday);
                user.setSex(sex);
                user.setEmail(email);
                user.setPhone(phone);
                user.setDeptId(deptId);
                user.setPositionId(positionId);
                // 完善账号信息
                user.setSalt(ShiroKit.getRandomSalt(5));
                user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
                user.setStatus(ManagerStatus.OK.getCode());
                
                //添加首字母与全拼信息
                user.setInitials(PinyinUtil.converterToFirstSpell(user.getName()));
                user.setPinyin(PinyinUtil.converterToSpell(user.getName()));
                this.baseMapper.insert(user);
                // 保存部门用户关系 表
                DeptUser deptUser = new DeptUser();
                deptUser.setUserId(user.getId());
                deptUser.setDeptId(deptId);
                deptUser.setRoleIds(roleId+"");
                deptUser.setIsPartTime(0);//0主部门 1兼职
                deptUser.insert();
            }else{
                throw new BizException("第"+(i+1)+"行：【"+name+"】用户已存在，请核对登录名和工号");
            }
        }
    }

    @Override
    public List<DeptUser> selectDeptUserByUserId(Long userId) {
        Wrapper<DeptUser> wrapper = new EntityWrapper<>();
        wrapper.eq("user_id", userId);
        List<DeptUser> ls = this.deptUserMapper.selectList(wrapper);
        return ls;
    }

    @Override
    public List<ZTreeNode> tree() {
        List<ZTreeNode> tree = this.baseMapper.tree();
        tree.add(ZTreeNode.createRoot());
        return tree;
    }

    @Override
    public List<ZTreeNode> treeAdmin() {
        List<ZTreeNode> tree = this.baseMapper.treeAdmin();
        tree.add(ZTreeNode.createRoot());
        return tree;
    }

    /**
     * 获取部门下用户_分页
     * @param page
     * @param map
     * @return
     */
    @Override
    public List<User> getDepUsers(Page<User> page, Map<String, Object> map) {
        return this.baseMapper.getDepUsers(page, map);
    }

    /**
     * .获取角色下用户_分页
     * @param page
     * @param map
     * @return
     */
    @Override
    public List<User> getRoleUsers(Page<User> page, Map<String, Object> map) {
        return this.baseMapper.getRoleUsers(page, map);
    }

    @Override
    public List<User> getUsersByIds(String userIds) {
        return this.baseMapper.getUsersByIds(userIds);
    }

    /**
     * @Description：删除用户
     * @Title: deleteUser
     * @param userId   
     * @see com.dhcc.core.modules.system.service.IUserService#deleteUser(java.lang.Long)
     */
	@Override
	public void deleteUser(Long userId) {
		// TODO Auto-generated method stub
		 // 删除部门用户关系 表
        Wrapper<DeptUser> wrapper1 = new EntityWrapper<DeptUser>();
        wrapper1.eq("user_id", userId);
        deptUserMapper.delete(wrapper1);
        // 删除用户表
        Wrapper<User> wrapper2 = new EntityWrapper<User>();
        wrapper2.eq("id", userId);
        this.baseMapper.delete(wrapper2);
	}
	
	@Override
    public User authenticate(String loginName, String password) {
        User user = this.getByLoginName(loginName);
        if (user != null && CommonUtil.equals(user.getPassword(), ShiroKit.md5(password, user.getSalt()))) {
            return user;
        }
        return null;
    }

}